MN.TP.CustomizeShowTl = function(){
    log('PAGE: Customizing show timeline widget');
    var tlp = MN.PlayerUI.Timeline.prototype;
    tlp._OnTimelineLoaded = function(qvt){
        //create a div for each show
        var h = this.timeline.GetView().offsetHeight;
        this.durAtLoad = qvt.Duration();
        if(this.fixedWidth)
            this.secPerPixel = this.durAtLoad / this.timelineWidth;
        else
            this.timelineWidth = this.durAtLoad / this.secPerPixel;

        var canvas = this.timeline.GetCanvas();
        var x = 0;
        var contentType = qvt.Metadata('mn_content_type') || 'vod';

		//clear out the old shows -- David Brown's 'daysplit' fix
		while(canvas.childNodes.length > 0)
			canvas.removeChild(canvas.childNodes[0]);

        for (var i=0; i < qvt.ShowCount(); i++)
        {
            var w = qvt.Duration(i) / this.secPerPixel;
            if(contentType == 'live')
                canvas.appendChild(this._MakeShowDiv(qvt.shows[i], qvt.PosToDatetime, x, w, h));
            else if(contentType == 'vod')
                canvas.appendChild(this._MakeShowDiv(qvt.shows[i], null, x, w, h));
            x += w;
        }

        canvas.style.width = x + 'px';

        var tlW = $(this.timelineID).offsetWidth/2;
        this.timeline.SetPadding(tlW, 0, tlW, 0);
    }

    tlp._MakeShowDiv = function(showObj, posToDateTime, x, w, tlHeight){
        var newDiv = MN.PopulateTemplate(this.template, showObj, posToDateTime);
        newDiv.style.position = 'absolute';
        newDiv.style.top = '0px';
        newDiv.style.left = x + 'px';
        newDiv.style.width = w + 'px';
        newDiv.style.height = tlHeight + 'px';
        newDiv.style.overflow = 'hidden';
        return newDiv;
    }

    tlp._UpdateUI = function(){   // called often to move the timeline
        if (!this.secPerPixel || !this.qmp)
            return;

        // if we're not using fancy scrubbing, then we don't want to update the UI based on
        // the player position during this time because the position won't be changing
        if (!this.fancyScrub && this.scrubbing)
            return;

        var pos = this.qmp.CurrentPosition();
        this.timeline.Center(pos / this.secPerPixel, 0);

        // we have to adjust the padding regularly in case the timeline is growing
        var tlW = $(this.timelineID).offsetWidth/2;
        //this.timeline.SetPadding(tlW, 0, qmp.Duration() / this.secPerPixel - tlW, 0);
        this.timeline.SetPadding(tlW, 0, tlW, 0);

        var posFormat = this.posFormat || 'HH:MM:SS';
        var contentType = this.qmp.CurrentQVT().Metadata('mn_content_type') || 'vod';
        //TODO: timezoneOverride
        if(contentType == 'live'){
            //pos = this.qmp.CurrentQVT().PosToDatetime(pos);
            //MN.SetInnerText($(this.posID), MN.ConvertToTimestamp(pos, "hh:mm:ss"));
						pos = this.qmp.CurrentPosition();
            MN.SetInnerText($(this.posID), MN.ConvertToTimestamp(pos, "hh:mm:ss"));
        }
        else if(contentType == 'vod'){
            posFormat = posFormat.toUpperCase();
            var dur = this.qmp.Duration();
            var durFormat = this.durFormat || posFormat;
            durFormat = durFormat.toUpperCase();
            var posTS = MN.ConvertToTimestamp(pos, posFormat);
            var durTS = MN.ConvertToTimestamp(dur, durFormat);
            if(durTS)
                MN.SetInnerText($(this.posID), posTS + ' / ' + durTS);
            else
                MN.SetInnerText($(this.posID), posTS);
        }
    }

    tlp._OnTimelinePositionChanged = function(x, y)
    {
        if (this.posID || this.posDurID)
        {
            var ih = this.posIncludeHours;
            var ssd = this.posSubSecDigits;
            var tlX = this.timeline.Center()[0] / this.timelineWidth;
            var dur = this.durAtLoad;
            var pos = (tlX * dur);
            var posFormat = this.posFormat || 'HH:MM:SS';
            var contentType = this.qmp.CurrentQVT().Metadata('mn_content_type') || 'vod';
            //TODO: timezoneOverride
            if(contentType == 'live'){
                //pos = this.qmp.CurrentQVT().PosToDatetime(pos);
                //MN.SetInnerText($(this.posID), MN.ConvertToTimestamp(pos, posFormat));
                pos = this.qmp.CurrentPosition();
            		MN.SetInnerText($(this.posID), MN.ConvertToTimestamp(pos, "hh:mm:ss"));
            }
            else if(contentType == 'vod'){
                posFormat = posFormat.toUpperCase();
                var dur = this.qmp.Duration();
                var durFormat = this.durFormat || posFormat;
                durFormat = durFormat.toUpperCase();
                var posTS = MN.ConvertToTimestamp(pos, posFormat);
                var durTS = MN.ConvertToTimestamp(dur, durFormat);
                if(durTS)
                    MN.SetInnerText($(this.posID), posTS + ' / ' + durTS);
                else
                    MN.SetInnerText($(this.posID), posTS);
            }
        }
    }

    log('PAGE: Done customizing show timeline widget');
}


MN.TP.ClipTimelineMode = function(timeline){

    timeline._UpdatePosDur = function(newPos){
        if(!this.posID && !this.posDurID && !this.scrubPosID || this.qmp.CurrentQVT() == null)
            return;

        var showNum = this.qmp.CurrentShow();
        if(showNum < 0 || showNum >= this.qmp.CurrentQVT().ShowCount()) //sometimes current show returns an invalid number when playing live
            showNum = this.qmp.CurrentQVT().ShowCount() - 1;

        //The clip timeline always shows the position/duration of the clip, and so a "24-hour" timestamp is used,
        //regardless of whatever else
        var posFormat = this.posFormat || 'HH:MM:SS';
        posFormat = posFormat.toUpperCase();
        var pos = newPos - this.slider.minValue;
        var posTS = MN.ConvertToTimestamp(pos, posFormat);

        if(this.posID != null)
            MN.SetInnerText($(this.posID), posTS);

        if(this.posDurID != null){
            //if durFormat has not been specified, try to mimic the format of the position
            var durFormat = this.durFormat || posFormat;
            durFormat = durFormat.toUpperCase();
            var dur = this.qmp.CurrentQVT().Duration(showNum);
            var durTS = MN.ConvertToTimestamp(dur, durFormat);

            //The duration returned on a live clip doesn't get updated until the whole timeline
            //reloads (a fix is being worked on in the SDK), so the position will sometimes be
            //greater than the duration.  If this is the case, then don't display duration.
			//  ESMAS: added checking for MN.TP.onLive (true if watching live show -- SDK doesn't respond the same for Publish QVTs
            if((this.qmp.CurrentQVT().IsOpenEnded() && showNum == (this.qmp.CurrentQVT().ShowCount() - 1)) || !durTS || MN.TP.onLive){
                //MN.SetInnerText($(this.posDurID), posTS);
                pos = this.qmp.CurrentPosition();
            		MN.SetInnerText($(this.posDurID), MN.ConvertToTimestamp(pos, "hh:mm:ss"));
            }
            else
                MN.SetInnerText($(this.posDurID), posTS + ' / ' + durTS);
        }

        if(this.scrubPosID != null){
            var scrubFormat = this.scrubFormat || posFormat;
            scrubFormat = scrubFormat.toUpperCase();
            var scrubTS = MN.ConvertToTimestamp(pos, scrubFormat);
            $(this.scrubPosID).innerHTML = scrubTS
        }
    }

    timeline._UpdateDuration = function(){
        if(this.qmp.CurrentQVT()){
            var showNum = this.qmp.CurrentShow();
            if(showNum < 0 || showNum >= this.qmp.CurrentQVT().ShowCount())
                showNum = this.qmp.CurrentQVT().ShowCount() - 1;

            var start = this.qmp.CurrentQVT().StartTime(showNum);
            var stop = this.qmp.CurrentQVT().StopTime(showNum);

            if(start >= 0 && stop){
                this.slider.SetRange(start, stop);
            }
        }
    }
}

MN.TP.TradTimelineMode = function(timeline){

    timeline._UpdatePosDur = function(newPos){
        if(!this.posID && !this.posDurID && !this.scrubPosID || this.qmp.CurrentQVT() == null)
            return;

        var qvt = this.qmp.CurrentQVT();
        var contentType = qvt.Metadata('mn_content_type') || 'vod';
        var posFormat = this.posFormat || 'HH:MM:SS';
        var posTS;

        //TODO: timezone override
        if(contentType == 'live'){
            posTS = MN.ConvertToTimestamp(qvt.PosToDatetime(newPos), posFormat);
        }
        //If content is vod do not use PosToDateTime() and force to 24 hour timestamp.
        //to obtain the position.  This makes it so that the beginning of the timeline is 0 time
        else if(contentType == 'vod'){
            posFormat = posFormat.toUpperCase();
            posTS = MN.ConvertToTimestamp(newPos, posFormat);
        }

        if(this.posID != null)
            MN.SetInnerText($(this.posID), pos);

        if(this.posDurID != null){
            //if live content, don't display duration,
            //just a convention that we thought would be nice to enforce
            if(contentType == 'live') {
                //MN.SetInnerText($(this.posDurID), posTS);
                var pos = this.qmp.CurrentPosition();
            		MN.SetInnerText($(this.posDurID), MN.ConvertToTimestamp(pos, "hh:mm:ss"));
            }
            else if(contentType == 'vod'){
                var durFormat = this.durFormat || posFormat;
                durFormat = durFormat.toUpperCase();
                var durTS = MN.ConvertToTimestamp(this.qmp.Duration(), durFormat);
                MN.SetInnerText($(this.posDurID), posTS + ' / ' + durTS);
            }
        }

        if(this.scrubPosID != null){
            var scrubFormat = this.scrubFormat || posFormat;
            if(contentType == 'vod')
                scrubFormat = scrubFormat.toUpperCase();
            var scrubTS = MN.ConvertToTimestamp(newPos, scrubFormat);
            MN.SetInnerText($(this.scrubPosID), scrubTS);
        }

    }

    timeline._UpdateDuration = function(){
        this.slider.SetRange(0, this.qmp.Duration());
    }
}
